package lightrain.db;

import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import javax.sql.DataSource;

import lightrain.db.dialect.impl.AbstractDialect;
import lightrain.db.dialect.impl.MySqlDialect;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;


public class NRepository<M extends Model<M,Id>,Id> {
	
	
	@Autowired
	private JdbcTemplate  jdbcTemplate;

	
	@SuppressWarnings("unchecked")
	private Class<M> getModelClass(){
		return (Class<M>) (((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
	}
	
	public M db(){
		return db(getModelClass());
	}
	
	
	public M db(Class<?> modelClass){
		M model = createModel(modelClass);
		model.setDb(jdbcTemplate);
		model.setDialect(new MySqlDialect(model));
		return model;
	}
	
	public M db(Class<?> modelClass,DataSource dataSource){
		M model = createModel(modelClass);
		model.setDb(dataSource);
		model.setDialect(new MySqlDialect(model));
		return model;
	}
	
	
	public M db(Class<?> modelClass,JdbcTemplate jdbcTemplate){
		M model = createModel(modelClass);
		model.setDb(jdbcTemplate);
		model.setDialect(new MySqlDialect(model));
		return model;
	}
	
	public M db(Class<?> modelClass,JdbcTemplate jdbcTemplate,AbstractDialect dialect){
		M model = createModel(modelClass);
		dialect.setModel(model);
		model.setDb(jdbcTemplate);
		model.setDialect(dialect);
		return model;
	}
	
	public M db(Class<?> modelClass,String alias,String[] columns){
		return db(modelClass).tableAlias(alias).column(columns);
	}
	
	public M db(Class<?> modelClass,String...columns){
		return db(modelClass, "", columns);
	}

	
	@SuppressWarnings("unchecked")
	private M createModel(Class<?> modelClass){
		try {
			return (M) modelClass.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public void saveBatch(final List<M> models){
		db().saveBatch(models);
	}
	
	public int update(M update){
		 return db().setAll(update).update();
	}
	
	
	public int update(Map<String, Object> data){
		 return db().setAll(data).update();
	}
	
	public int delete(Id id){
		return db().delete(id);
	}
	
	
	public Id save(M model){
		return db().save(model);
	}
	
	public Id save(Map<String, Object> data){
		createModel(getModelClass());
		return db().setAll(data).save();
	}
	
	/**
	 * 通过id获取
	 * @param id
	 * @return
	 */
	public M get(Id id){
		return db().find(id);
	}
	
	public List<M> getAll(){
		return db().select();
	}
	
	public List<M> getAll(int page,int pageSize){
		return db().select(page,pageSize);
	}
	
	public List<M> getAll(Integer page,Integer size,Consumer<M> consumer){
		M db = db();
		consumer.accept(db);
		return db.select(page, size);
	}
	
	public Pager<M> getListPager(int page,int pageSize){
		return db().pager(page, pageSize);
	}
	
	public Pager<M> getListPager(int page,int pageSize,Consumer<M> consumer){
		M db = db();
		consumer.accept(db);
		return db.pager(page, pageSize);
	}
	
	
	public List<M> getAll(Consumer<M> consumer){
		M db = db();
		consumer.accept(db);
		return db.select();
	}
	
	public M get(Consumer<M> consumer){
		M db = db();
		consumer.accept(db);
		return db.find();
	}
	 
	public int getCount(Consumer<M> consumer){
		M db = db();
		consumer.accept(db);
		return db.getCountTotal();
	}
	

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	
}
